ACM_SCHEMA_FILE = "/etc/xen/acm-security/policies/security_policy.xsd"
+ACM_LABEL_UNLABELED = "__UNLABELED__"
+ACM_LABEL_UNLABELED_DISPLAY = "unlabeled"
+
class ACMPolicy(XSPolicy):
"""
ACMPolicy class. Implements methods for getting information from
return -xsconstants.XSERR_POLICY_INCONSISTENT, "", ""
vms_with_chws = []
- chws_by_vm = {}
+ chws_by_vm = { ACM_LABEL_UNLABELED : [] }
for v in vms:
if v.has_key("chws"):
vms_with_chws.append(v["name"])
chws_by_vm[v["name"]] = v["chws"]
+
+
if bootstrap in vms_with_chws:
vms_with_chws.remove(bootstrap)
vms_with_chws.sort()
else:
vms_with_chws.sort()
+ if ACM_LABEL_UNLABELED in vms_with_chws:
+ vms_with_chws.remove(ACM_LABEL_UNLABELED) ; # @1
+
vms_with_stes = []
- stes_by_vm = {}
+ stes_by_vm = { ACM_LABEL_UNLABELED : [] }
for v in vms:
if v.has_key("stes"):
vms_with_stes.append(v["name"])
stes_by_vm[v["name"]] = v["stes"]
+
if bootstrap in vms_with_stes:
vms_with_stes.remove(bootstrap)
vms_with_stes.sort()
else:
vms_with_stes.sort()
+ if ACM_LABEL_UNLABELED in vms_with_stes:
+ vms_with_stes.remove(ACM_LABEL_UNLABELED) ; # @2
+
resnames = self.policy_get_resourcelabel_names()
resnames.sort()
stes_by_res = {}
if r.has_key("stes"):
stes_by_res[r["name"]] = r["stes"]
+ if ACM_LABEL_UNLABELED in resnames:
+ resnames.remove(ACM_LABEL_UNLABELED)
+
max_chw_ssids = 1 + len(vms_with_chws)
max_chw_types = 1 + len(vms_with_chws)
max_ste_ssids = 1 + len(vms_with_stes) + len(resnames)
pr_bin += "\x00"
# Build chinese wall part
+ vms_with_chws.insert(0, ACM_LABEL_UNLABELED)
+
cfses_names = self.policy_get_chwall_cfses_names_sorted()
cfses = self.policy_get_chwall_cfses()
chw_running_types_offset,
chw_conf_agg_offset)
chw_bin_body = ""
- # simulate __NULL_LABEL__
- for c in chws:
- chw_bin_body += struct.pack("!h",0)
+
# VMs that are listed and their chinese walls
for v in vms_with_chws:
for c in chws:
chw_bin += "\x00"
# Build STE part
+ vms_with_stes.insert(0, ACM_LABEL_UNLABELED) # Took out in @2
+
steformat="!iiiii"
ste_bin = struct.pack(steformat,
ACM_STE_VERSION,
struct.calcsize(steformat))
ste_bin_body = ""
if stes:
- # Simulate __NULL_LABEL__
- for s in stes:
- ste_bin_body += struct.pack("!h",0)
- # VMs that are listed and their chinese walls
+ # VMs that are listed and their STE types
for v in vms_with_stes:
unknown_ste |= (set(stes_by_vm[v]) - set(stes))
for s in stes:
back['uuid'] = uuid
if security.on():
- (label, ssidref, policy) = \
- security.get_res_security_details(uname)
- domain_label = self.vm.get_security_label()
- if domain_label:
- rc = security.res_security_check_xapi(label, ssidref, policy,
- domain_label)
- if rc == 0:
- raise VmError("VM's access to block device '%s' denied." %
- uname)
- else:
- raise VmError("VM must have a security label.")
+ self.do_access_control(config, uname)
devid = blkif.blkdev_name_to_number(dev)
if devid is None:
return (devid, back, front)
+ def do_access_control(self, config, uname):
+ (label, ssidref, policy) = \
+ security.get_res_security_details(uname)
+ domain_label = self.vm.get_security_label()
+ if domain_label:
+ rc = security.res_security_check_xapi(label, ssidref, policy,
+ domain_label)
+ if rc == 0:
+ raise VmError("VM's access to block device '%s' denied" %
+ uname)
+ else:
+ from xen.util.acmpolicy import ACM_LABEL_UNLABELED
+ if label != ACM_LABEL_UNLABELED:
+ raise VmError("VM must have a security label to access "
+ "block device '%s'" % uname)
def reconfigureDevice(self, _, config):
"""@see DevController.reconfigureDevice"""
return ACM_OK;
}
+
static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
{
struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
chwall_ssidp->chwall_ssidref =
GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
- if ( (chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
- || (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) )
+ if ( chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
{
- printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n",
+ printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset "
+ "(0).\n",
__func__, chwall_ssidp->chwall_ssidref);
xfree(chwall_ssidp);
return ACM_INIT_SSID_ERROR;
return ACM_OK;
}
+
static void chwall_free_domain_ssid(void *chwall_ssid)
{
xfree(chwall_ssid);
read_lock(&ssid_list_rwlock);
- /* go through all domains and adjust policy as if this domain was started now */
+ /* go through all domains and adjust policy as if this domain was
+ * started now
+ */
for_each_acmssid( rawssid )
{
chwall_ssid =
/* b) check for conflict */
for ( i = 0; i < chwall_buf->chwall_max_types; i++ )
- if (conflict_aggregate_set[i] &&
- ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i])
+ if ( conflict_aggregate_set[i] &&
+ ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i] )
{
printk("%s: CHINESE WALL CONFLICT in type %02x.\n",
__func__, i);
goto out;
}
+
/* set violation and break out of the loop */
- /* c) adapt conflict aggregate set for this domain (notice conflicts) */
+ /* c) adapt conflict aggregate set for this domain
+ * (notice conflicts)
+ */
for ( i = 0; i < chwall_buf->chwall_max_conflictsets; i++ )
{
int common = 0;
/* check if conflict_set_i and ssidref have common types */
for ( j = 0; j < chwall_buf->chwall_max_types; j++ )
- if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
- ssidrefs[chwall_ssidref *
- chwall_buf->chwall_max_types + j])
+ if ( conflict_sets[i * chwall_buf->chwall_max_types + j] &&
+ ssidrefs[chwall_ssidref *
+ chwall_buf->chwall_max_types + j] )
{
common = 1;
break;
}
- if (common == 0)
+
+ if ( common == 0 )
continue; /* try next conflict set */
- /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+
+ /* now add types of the conflict set to conflict_aggregate_set
+ * (except types in chwall_ssidref)
+ */
for ( j = 0; j < chwall_buf->chwall_max_types; j++ )
- if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
- !ssidrefs[chwall_ssidref *
- chwall_buf->chwall_max_types + j])
+ if ( conflict_sets[i * chwall_buf->chwall_max_types + j] &&
+ !ssidrefs[chwall_ssidref *
+ chwall_buf->chwall_max_types + j] )
conflict_aggregate_set[j]++;
}
}
out:
read_unlock(&ssid_list_rwlock);
return violation;
- /* returning "violation != 0" means that the currently running set of domains would
- * not be possible if the new policy had been enforced before starting them; for chinese
- * wall, this means that the new policy includes at least one conflict set of which
- * more than one type is currently running */
+ /* returning "violation != 0" means that the currently running set of
+ * domains would not be possible if the new policy had been enforced
+ * before starting them; for chinese wall, this means that the new
+ * policy includes at least one conflict set of which more than one
+ * type is currently running
+ */
}
memset(conflict_aggregate_set, 0,
sizeof(domaintype_t) * chwall_buf->chwall_max_types);
- /* 3. now re-calculate the state for the new policy based on running domains;
- * this can fail if new policy is conflicting with running domains */
+ /* 3. now re-calculate the state for the new policy based on
+ * running domains; this can fail if new policy is conflicting
+ * with running domains
+ */
if ( chwall_init_state(chwall_buf, ssids,
conflict_sets, running_types,
conflict_aggregate_set,
chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
- if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
- {
- printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
- __func__);
- return ACM_ACCESS_DENIED; /* catching and indicating config error */
- }
-
- if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
+ if ( chwall_ssidref >= chwall_bin_pol.max_ssidrefs )
{
printk("%s: ERROR chwall_ssidref > max(%x).\n",
__func__, chwall_bin_pol.max_ssidrefs - 1);
return ACM_ACCESS_DENIED;
}
+
/* A: chinese wall check for conflicts */
- for (i = 0; i < chwall_bin_pol.max_types; i++)
- if (chwall_bin_pol.conflict_aggregate_set[i] &&
- chwall_bin_pol.ssidrefs[chwall_ssidref *
- chwall_bin_pol.max_types + i])
+ for ( i = 0; i < chwall_bin_pol.max_types; i++ )
+ if ( chwall_bin_pol.conflict_aggregate_set[i] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref *
+ chwall_bin_pol.max_types + i] )
{
printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
return ACM_ACCESS_DENIED;
}
/* B: chinese wall conflict set adjustment (so that other
- * other domains simultaneously created are evaluated against this new set)*/
+ * other domains simultaneously created are evaluated against
+ * this new set)
+ */
for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )
{
int common = 0;
common = 1;
break;
}
- if (common == 0)
+ if ( common == 0 )
continue; /* try next conflict set */
/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
for ( j = 0; j < chwall_bin_pol.max_types; j++ )
common = 1;
break;
}
+
if ( common == 0 )
- continue; /* try next conflict set */
- /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ {
+ /* try next conflict set */
+ continue;
+ }
+
+ /* now add types of the conflict set to conflict_aggregate_set
+ (except types in chwall_ssidref) */
for ( j = 0; j < chwall_bin_pol.max_types; j++ )
if ( chwall_bin_pol.
conflict_sets[i * chwall_bin_pol.max_types + j]
common = 1;
break;
}
- if (common == 0)
- continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
- /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ if ( common == 0 )
+ {
+ /* try next conflict set, this one does not include
+ any type of chwall_ssidref */
+ continue;
+ }
+
+ /* now add types of the conflict set to conflict_aggregate_set
+ (except types in chwall_ssidref) */
for ( j = 0; j < chwall_bin_pol.max_types; j++ )
if ( chwall_bin_pol.
conflict_sets[i * chwall_bin_pol.max_types + j]